package com.zengjianjun.es.demo.service.impl;

import com.zengjianjun.es.demo.common.EsConstant;
import com.zengjianjun.es.demo.entity.EsGaidEntity;
import com.zengjianjun.es.demo.mapper.EsGaidMapper;
import com.zengjianjun.es.demo.param.EsGaidParam;
import com.zengjianjun.es.demo.service.EsGaidService;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.ScriptType;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zengjianjun
 */
@Service
public class EsGaidServiceImpl implements EsGaidService {

    @Resource
    private EsGaidMapper esGaidMapper;
    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public long countByConditions(EsGaidParam param) {
        CriteriaQuery query = new CriteriaQuery(this.getCriteria(param));
        return elasticsearchRestTemplate.count(query, EsGaidEntity.class);
    }

    @Override
    public List<EsGaidEntity> findList(EsGaidParam param) {
        CriteriaQuery query = new CriteriaQuery(this.getCriteria(param));
        SearchHits<EsGaidEntity> search = elasticsearchRestTemplate.search(query, EsGaidEntity.class);
        return search.map(SearchHit::getContent).toList();
    }

    @Override
    public void updateCatAndSubCat(EsGaidParam param, String cat, String subCat) {
        Map<String, Object> updateMap = new HashMap<>();
        updateMap.put("cat", cat);
        updateMap.put("subCat", subCat);
        // 构建更新请求
        UpdateQuery updateQuery = UpdateQuery.builder(new CriteriaQuery(this.getCriteria(param)))
                .withScript("ctx._source.cat = params.cat; ctx._source.subCat = params.subCat;")
                .withScriptType(ScriptType.INLINE)
                .withLang("painless")
                .withParams(updateMap).build();

        // 执行更新操作
        elasticsearchRestTemplate.updateByQuery(updateQuery, IndexCoordinates.of(EsConstant.INDEX_GAID));
    }

    @Override
    public void save(EsGaidEntity entity) {
        this.esGaidMapper.save(entity);
    }

    @Override
    public void saveAll(List<EsGaidEntity> entityList) {
        this.esGaidMapper.saveAll(entityList);
    }

    private Criteria getCriteria(EsGaidParam param) {
        Criteria criteria = new Criteria();
        if (param.getGaid() != null) {
            criteria.and(Criteria.where("gaid").is(param.getGaid()));
        }
        // 添加source相等条件
        if (param.getPackageName() != null) {
            criteria.and(Criteria.where("packageName").is(param.getPackageName()));
        }
        // 添加source相等条件
        if (param.getSource() != null) {
            criteria.and(Criteria.where("source").is(param.getSource()));
        }
        // 添加country相等条件
        if (param.getCountry() != null) {
            criteria.and(Criteria.where("country").is(param.getCountry()));
        }
        // 添加tags条件，满足一个列表中的其中一个但不包含另一个列表
        List<String> includedTags = param.getIncludedTags();
        if (includedTags != null && !includedTags.isEmpty()) {
            criteria.and(Criteria.where("tags").in(includedTags));
        }
        List<String> excludedTags = param.getExcludedTags();
        if (excludedTags != null && !excludedTags.isEmpty()) {
            criteria.and(Criteria.where("tags").notIn(excludedTags));
        }
        if (param.getStartCreateTime() != null && param.getEndCreateTime() != null) {
            criteria.and(Criteria.where("createTime").between(param.getStartCreateTime(), param.getEndCreateTime()));
        }
        return criteria;
    }
}
